package cn.com.generaldata.os.service.impl;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.lang.Lang;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.generaldata.jsme_indicator_system.entity.Dustry;
import cn.com.generaldata.jsme_indicator_system.entity.IndicatorProduction;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

/**
 * 产业部门基本流量表service.
 */
@Service
public class IndicatorProductionService {

	@Autowired
	private DustryService dustryService;

	@Autowired
	private Dao dao;

	// 基本流量表距阵的缓存
	private Cache<Integer, double[][]> productionMatrixCache = CacheBuilder.newBuilder()
			.expireAfterAccess(1, TimeUnit.DAYS)
			.build();

	/**
	 * 检查是否存在该年份的直接消耗系数数据
	 * 
	 * @param year
	 * @return
	 */
	public boolean checkHasData(int year) {
		Cnd cnd = Cnd.where("year", "=", year);
		return dao.count(IndicatorProduction.class, cnd) > 0 ? true : false;
	}

	/**
	 * 获取基本流量表的距阵
	 * 
	 * @param year 年份
	 * @return
	 */
	public double[][] getProductionMatrix(final int year) {
		double[][] productionMatrix = null;
		try {
			productionMatrix = productionMatrixCache.get(year, new Callable<double[][]>() {
				@Override
				public double[][] call() {

					return buildProductionMatrix(year);
				}
			});
		} catch (ExecutionException e) {
			throw Lang.makeThrow("获取基本流量表错误,year:%d", year, e);
		}

		return productionMatrix;
	}

	/**
	 * 根据年份构造基本流量表两维距阵.
	 * 
	 * @param year
	 * @return
	 */
	private double[][] buildProductionMatrix(int year) {
		List<Dustry> dustries = dustryService.getDustrys(year);
		double[][] matrix = new double[dustries.size()][3];
		for (int row = 0, rowCount = dustries.size(); row < rowCount; row++) {
			Dustry rowDustry = dustries.get(row);
			Cnd cnd = Cnd.where("dustryId", "=", rowDustry.getId())
					.and("year", "=", year);
			IndicatorProduction production = dao.fetch(IndicatorProduction.class, cnd);
			if (production != null) {
				matrix[row][0] = production.getExpenditure();
				matrix[row][1] = production.getGross();
				matrix[row][2] = production.getExport();
			}
		}
		return matrix;
	}

}
